#include "AudioPlayThread.h"

// 音频
void pull_audio_data(void *userdata, Uint8 * stream, int len) {
    //  清空stream
    SDL_memset(stream, 0, len);
    //  取出缓冲数据
    AudioBuffer *buffer = (AudioBuffer *)userdata;
    if(buffer->len == 0) return;
    //  取len，bufferLen最小值，保证数据安全
    buffer->pullLen = (len > buffer->len) ? buffer->len : len;
    //  填充数据
    SDL_MixAudio(stream, buffer->data, buffer->pullLen, SDL_MIX_MAXVOLUME);
    buffer->data += buffer->pullLen;
    buffer->len -= buffer->pullLen;
}

void AudioPlayThread::run() {    
    if (SDL_Init(SDL_INIT_AUDIO)) {
        return;
    }
    SDL_AudioSpec spec;
    //  采样率
    spec.freq = 48000;
    //  采样格式（s16le）
    spec.format = AUDIO_F32LSB;
    //  声道数
    spec.channels = 1;
    //  音视频缓存区的样本数量（必须是2的幂）
    spec.samples = 1024;
    //  回调函数
    spec.callback = pull_audio_data;

    AudioBuffer buffer;
    spec.userdata = &buffer;
    //  打开音频设备
    if (SDL_OpenAudio(&spec, nullptr)) {
        //  清除所有初始化的子系统
        SDL_Quit();
        return;
    }

    QFile file = fileModel.file();
    //  打开文件
    if (!file.open(QFile::ReadOnly)) {
        //  关闭音频设备
        SDL_CloseAudio();
        //  清楚所有初始化的子系统
        SDL_Quit();
        return;
    }

    //  开始播放音频（0表示播放，其他的表示暂停）
    SDL_PauseAudio(0);
    //  每个样本占用的字节数
    int bytes_per_sample = 32 * spec.channels >> 3;
    //  文件缓冲区的大小
    int buffer_size = 1024 * bytes_per_sample;
    //  文件缓冲区的数量
    Uint8 data[buffer_size];

    while (!isInterruptionRequested()) {
        if (buffer.len > 0) continue;
        buffer.len = file.read((char *)data, buffer_size);
        //  文件数据已经读取完毕
        if (buffer.len <= 0) {
            //  剩余的样本数量
            int samples = buffer.pullLen / bytes_per_sample;
            int ms = samples * 1000 / spec.freq;
            SDL_Delay(ms);
            break;
        }
        //  读取到的文件数据
        buffer.data = data;
    }
    file.close();
    SDL_CloseAudio();
    SDL_Quit();
}
